home *** CD-ROM | disk | FTP | other *** search
/ The PC-SIG Library 10 / The PC-Sig Library - Shareware for the IBM PC and Compatibles (PC-SIG)(Tenth Edition Disks 1-2804)(1991).iso / PC_SIGCD / 04 / 1 / DISK0416.ZIP / ROFF4.C < prev    next >
C/C++ Source or Header  |  1985-08-10  |  18KB  |  553 lines

  1. /********************************************************/
  2. /*                                                      */
  3. /*                  ROFF4, Version 1.60                 */
  4. /*                                                      */
  5. /*(C) 1983,4 by Ernest E. Bergmann                      */
  6. /*              Physics, Building #16                   */
  7. /*              Lehigh Univerisity                      */
  8. /*              Bethlehem, Pa. 18015                    */
  9. /*                                                      */
  10. /* Permission is hereby granted for all commercial and  */
  11. /* non-commercial reproduction and distribution of this */
  12. /* material provided this notice is included.           */
  13. /*                                                      */
  14. /********************************************************/
  15. #include "roff4.h"
  16. /*****************MAIN************MAIN*********/
  17. main(argc, argv)
  18. int argc;
  19. char **argv;
  20. {
  21.       char option,*macq(),*pc;
  22.       char filename[20];
  23.       struct divfd *pd;
  24.       LASTCH=NULL;
  25.       dioinit (&argc, argv);  /* directed I/O */
  26.       fprintf(STDERR,"ROFF4, version 1.60, Mar 10, 1984\n");
  27.       fprintf(STDERR,"        (c) 1983,4 by\n");
  28.       fprintf(STDERR,"E. E. Bergmann, Physics,Bldg. #16\n");
  29.       fprintf(STDERR,"Lehigh University, Bethlehem PA 18015\n");
  30. #ifdef DEBUGON
  31.       debug = FALSE;
  32. #endif
  33.       if(FALSE) {
  34.             putchar('\r');
  35.             putchar('\n');
  36.       }/*for linkage purposes only!*/
  37.       if (argc == 1)
  38.       { 
  39.             fprintf(STDERR,"USAGE:  ROFF4 file1\n  more than one file OK\n");
  40.             exit();
  41.       }
  42.       argv++;
  43.       init_defaults();
  44.       while ( --argc > 0 )
  45.       { 
  46.             strcpy (filename, *argv++);
  47.             fprintf(STDERR,"Now processing <%s>\n",filename );
  48.             if(filename[0]=='-')
  49.             {
  50.                   option=toupper(filename[1]);
  51.                   if(option=='M') showm();
  52. #ifdef DEBUGON
  53.                   else if(option=='B') debug=TRUE;
  54. #endif
  55.                   else if(option=='D') showd();
  56.                   else if(option=='F') putchar(FORMF);
  57.                   else if(option=='G') gloss();
  58.                   else if(option=='I') showit();
  59.                   else if(option=='R') showr();
  60.                   else if(option=='S') PAGESTOP=TRUE;
  61.                   else if(option=='O') range(&filename[2]);
  62.                   else    {
  63.                         KEYBD=option;
  64.                         dolns();
  65.                         fprintf(STDERR,"End of keyboard input <%c>\n",
  66.                         KEYBD);
  67.                         KEYBD=FALSE;
  68.                   }
  69.                   continue;
  70.             }
  71.             if(pd=(struct divfd *) find2(filename,DLINK)) dclose(pd);
  72.             if (NULL == (IOBUF=fopen( filename,"r")))
  73.             {
  74.                   fprintf(STDERR,"can't open <%s>\n",filename );
  75.                   continue;
  76.             }
  77.             else dolns();
  78.             if(VLINENO>0||OUTBUF[0]) space(HUGE);
  79.             fprintf(STDERR,"Done processing <%s>\n", filename );
  80.             fclose(IOBUF);
  81.       }         /* end while (--argc > 0 ) */
  82.       dsclose();
  83.       dioflush();
  84. }               /* end main()          */
  85. /****************************************/
  86. dolns() /*do processing of lines*/
  87. {
  88.       char *pc;
  89.       int typ;
  90.       int e;
  91.       char *fgets2();
  92.       BINP=0;
  93.       while((e=(int) fgets2(LINE,IOBUF))||FPTR) /*until EOF*/
  94.       {
  95.             if(e) {
  96.                   if(LINE[0]==COMMAND)
  97.                   {
  98.                         if(pc=macq(LINE)) pbmac(pc,LINE);
  99.                         else comand(LINE);
  100.                   }
  101.                   else text(LINE);
  102.             }
  103.             else endso();
  104.       }
  105. }
  106. /**************************************************************
  107. initializes the global variables governing the execution of the
  108.  format commands.
  109. **************************************************************/
  110. init_defaults()
  111. {
  112.       initsk(&FILL,FI_DEF);  /* yes we want filled lines */
  113.       initsk(&LSVAL,LS_DEF);  /* line spacing = 1 */
  114.       initsk(&INVAL,IN_DEF);  /* left margin indent  0 */
  115.       initsk(&RMVAL,RM_DEF);  /* right margin = page width  */
  116.       TIVAL = IN_DEF; /* left margin temporary indent    0 */
  117.       CEVAL = 0;      /* next n lines to be centered -  0  */
  118.       PAGESTOP = FALSE;
  119.       FFEED = FF_INI;
  120.       FIRSTPAGE=1;
  121.       LASTPAGE=30000;/*infinite*/
  122.       JUSTIFY=JU_INI;
  123.       initsk(&PLVAL,PL_DEF);
  124.       initsk(&M1VAL,M1_DEF);
  125.       initsk(&M2VAL,M2_DEF);
  126.       initsk(&M3VAL,M3_DEF);
  127.       initsk(&M4VAL,M4_DEF);
  128.       initsk(&SCVAL,SC_INI);
  129.       initsk(&OWVAL,OW_INI);
  130.       initsk(&TABSIZ,TS_DEF);
  131.       initsk(&TCVAL,TC_DEF);
  132.       initsk(&CFVAL,CF_DEF);
  133.       initsk(&ICVAL,IC_DEF);
  134.       CURPAG = 0;
  135.       NEWPAG = 1;
  136.       FRQ=FRSTRING=WHSTRING=0;
  137.       FRVAL=1;
  138.       FVLINENO=FPLINENO = PLINENO = 0;
  139.       VLINENO = -1;
  140.       BOTTOM = PLVAL - M3VAL - M4VAL;
  141.       OUTW=OUTPOS=OUTTOP=OUTBOT=OLDLN=OLDBOT=OUTWRDS = 0;
  142.       OUTBUF [0] = '\0';
  143.       DIR = 0;
  144.       EH2 = EH3 = EHEAD ;
  145.       OH2 = OH3 = OHEAD ;
  146.       *EHEAD = *OHEAD = '\0' ;
  147.       EF2 = EF3 = EFOOT ;
  148.       OF2 = OF3 = OFOOT ;
  149.       *EFOOT = *OFOOT = '\0' ;
  150.       setmem(CPTR,2*(128-' '),0);
  151.       setmem(TPTR,2*(128-' '),0);
  152.       TREND = TRTBL;
  153.       OUTBUF2[0]=BPOS=0;
  154.       initxu();
  155.       MCNT=1;
  156.       UF=XF=FALSE;
  157.       setmem(&DBUF,LSZ,FALSE);
  158.       DPOS=-1;
  159.       FPTR=DLINK=RLINK=SLINK=MLINK=0;
  160.       KPTR=KLINE;
  161.       *KLINE=0;
  162.       KEYBD=FALSE;
  163.       complete();
  164. }
  165. /****************************************/
  166.  
  167. /*      July 1: \#\ replaced by current page number.
  168.         June 8: concatenate lines with trailing '\'
  169.         June 1, 1983 modified for macro string processing.
  170.         fgets2: (May 2, 1983 by EEB fix to reset parity)
  171.         This next function is like "gets", except that
  172.         a) the line is taken from a buffered input file instead
  173.         of from the console, and b) the newline is INCLUDED in
  174.         the string and followed by a null byte. 
  175.         
  176.         This one is a little tricky due to the CP/M convention
  177.         of having a carriage-return AND a linefeed character
  178.         at the end of every text line. In order to make text
  179.         easier to deal with from C programs, ngetc()
  180.         automatically strips off the CR from any CR-LF
  181.         combinations that come in from the file. Any CR
  182.         characters not immediately followed by LF are left
  183.         intact. The LF is included as part of the string, and
  184.         is followed by a null byte. (Note that LF equals
  185.         "newline".) There is no limit to how long a line
  186.         can be here; care should be taken to make sure the
  187.         string pointer passed to fgets points to an area
  188.         large enough to accept any possible line length
  189.         (a line must be terminated by a newline (LF, or '\n')
  190.         character before it is considered complete.)  The
  191.         ngetc() also resets the parity bit.
  192.  
  193.         The value NULL (defined to be 0 here) is returned
  194.         on EOF, whether it be a physical EOF (attempting to
  195.         read past last sector of the file) OR a logical EOF
  196.         (encountered a control-Z.) The 1.3 version didn't
  197.         recognize logical EOFs, because I did't realize how
  198.         SIMPLE it was to implement a buffered I/O "ungetc"
  199.         function.
  200. */
  201.  
  202. char *fgets2(s,iobuf)
  203. char *s;
  204. FILE *iobuf;
  205. {
  206.       int count,c,i,*pw,pnum;
  207.       char *cptr,*pc;
  208.       char wbuf[LSZ],*fnd;
  209.       count = MAXLINE;
  210.       cptr = s;
  211.       if ( (c=ngetc(iobuf))==EOF)
  212.             return NULL;
  213.  
  214.       do {    
  215.             if(c==ICVAL)/*need macro substitution*/
  216.             {
  217.                   for(i=0;ICVAL!=(wbuf[i]=ngetc(iobuf));i++)
  218.                   {
  219.                         if(wbuf[i]=='\n')
  220.                         {
  221.                               if(i) putback('\n');
  222.                               break;
  223.                         }
  224.                   }
  225.                   if (i) {
  226.                         wbuf[i]='\0';
  227.                         if ((*wbuf==NUMSIGN) && (i==1))
  228.                         {
  229.                               if((VLINENO>=PLVAL)
  230.                                   ||(VLINENO<0)) pnum=NEWPAG;
  231.                               else pnum=CURPAG;
  232.                               itoc(pnum,wbuf,10);
  233.                               pbstr(wbuf);
  234.                         }
  235.                         else if(pw=(int *) find2(wbuf,RLINK))
  236.                         {
  237.                               itoc(*pw,wbuf,10);
  238.                               pbstr(wbuf);
  239.                         }
  240.                         else if(fnd=(char *) find2(wbuf,SLINK)) pbstr(fnd);
  241.                         else{
  242.                               start();
  243.                               pc=wbuf;
  244.                               pw=(int *) TREND;
  245.                               *(pw++)=SLINK;
  246.                               transfer(&pc,&pw,'\0');
  247.                               fprintf(STDERR,"\n%cPlease define <%s>:",
  248.                               BELL,wbuf);
  249.                               fflush(STDERR);
  250.                               gets(wbuf);
  251.                               pc=wbuf;
  252.                               transfer(&pc,&pw,'\0');
  253.                               SLINK=(int *) TREND;
  254.                               TREND=(char *)pw;
  255.                               complete();
  256.                               pbstr(wbuf);
  257.                         }
  258.                         continue;
  259.                   }
  260.                   else if(*wbuf!='\n') putback(ICVAL); 
  261.                   c=ngetc(iobuf);
  262.             }
  263.             if ((*cptr++ = c) == '\n') break;
  264.  
  265.       } 
  266.       while (count--&&(c=ngetc(iobuf))!=EOF);
  267.  
  268.       *cptr = '\0';
  269.       return(s);
  270. }
  271. /**************************************************************
  272. performs the formatting command returned by comtyp -sets global
  273.   variables ( indenting, underlining, etc. )
  274. **************************************************************/
  275. comand ( line )
  276. char *line;
  277. {
  278.       int c_type;    /* command type  */
  279.       int arg_val;    /* argument value, if any */
  280.       char arg_typ;   /* relative (+ or -) or absolute */
  281.       char wbuf[20];
  282.       int i;
  283.       c_type = comtyp (line);
  284. #ifdef DEBUGON
  285.       if DEBUG fprintf(STDERR,"COMAND %d,",c_type);
  286. #endif
  287.       if (c_type == UNKNOWN)
  288.       {
  289.             fprintf(STDERR, "UNKNOWN COMMAND: <%s>\n", line);
  290.             return;
  291.       }
  292.       arg_val = get_val ( line, &arg_typ );
  293. #ifdef DEBUGON
  294.       if DEBUG
  295.           fprintf(STDERR,"get_val returned arg_val=%d,arg_typ=%c\n",
  296.       arg_val,    arg_typ   );
  297. #endif
  298.       switch (c_type)
  299.       {
  300.       case IG : 
  301.             break;/* ignore remark */
  302.  
  303.       case FI :       /* filled lines  */
  304.             brk();
  305.             FILL = YES;
  306.             break;
  307.  
  308.       case NF :       /* non-filled lines */
  309.             brk();
  310.             FILL = NO;
  311.             break;
  312.  
  313.       case NJ :       /* non-justified lines */
  314.             JUSTIFY = NO;
  315.             break;
  316.  
  317.       case JU :       /* justified lines  */
  318.             JUSTIFY = YES;
  319.             break;
  320.  
  321.       case BR :       /* just cause a break */
  322.             brk();
  323.             break;
  324.  
  325.       case LS :       /* set line spacing value */
  326.             setS(&LSVAL, arg_val, arg_typ, LS_DEF, 1, HUGE );
  327.             break;
  328.  
  329.       case TI :       /* set temporary left indent */
  330.             brk();
  331.             set ( &TIVAL, arg_val, arg_typ, TI_DEF, 0, RMVAL );
  332.             break;
  333.  
  334.       case IN :       /* set left indent */
  335.             setS( &INVAL, arg_val, arg_typ, IN_DEF, 0, RMVAL-1 );
  336.             TIVAL = INVAL;
  337.             break;
  338.  
  339.       case RM:        /* set right margin */
  340.             setS( &RMVAL, arg_val, arg_typ, RM_DEF, TIVAL+1, OWVAL );
  341.             break;
  342.       case M1:        /* set topmost margin */
  343.             setS( &M1VAL, arg_val, arg_typ, M1_DEF,0,HUGE);
  344.             break;
  345.  
  346.       case M2:        /* set second top margin */
  347.             setS( &M2VAL, arg_val, arg_typ, M2_DEF,0,HUGE);
  348.             break;
  349.  
  350.       case M3:        /* set first bottom margin */
  351.             setS( &M3VAL, arg_val, arg_typ, M3_DEF,0,HUGE);
  352.             BOTTOM = PLVAL - M3VAL - M4VAL;
  353.             break;
  354.  
  355.       case M4:        /* set bottom-most margin */
  356.             setS(&M4VAL, arg_val, arg_typ, M4_DEF,0,HUGE);
  357.             BOTTOM = PLVAL - M3VAL - M4VAL;
  358.             break;
  359.  
  360.       case CE :       /* center next arg_val lines */
  361.             brk();
  362.             set ( &CEVAL, arg_val, arg_typ,CE_DEF,0, HUGE);
  363.             break;
  364.  
  365.       case HE :       /* get header title for pages */
  366.             gettl3 ( line, EHEAD, &EH2, &EH3 );
  367.             gettl3 ( line, OHEAD, &OH2, &OH3 );
  368.             break;
  369.  
  370.       case OH :       /*get odd header title*/
  371.             gettl3 ( line, OHEAD, &OH2, &OH3 );
  372.             break;
  373.  
  374.       case EH :       /*get even header title*/
  375.             gettl3 ( line, EHEAD, &EH2, &EH3 );
  376.             break;
  377.  
  378.       case FO :       /* get footer title for pages */
  379.             gettl3 ( line, EFOOT, &EF2, &EF3 );
  380.             gettl3 ( line, OFOOT, &OF2, &OF3 );
  381.             break;
  382.  
  383.       case OF :       /* get odd page footer title*/
  384.             gettl3 ( line, OFOOT, &OF2, &OF3 );
  385.             break;
  386.  
  387.       case EF :       /* get even page footer title*/
  388.             gettl3 ( line, EFOOT, &EF2, &EF3 );
  389.             break;
  390.  
  391.       case SP :       /* space down arg_val blank lines */
  392.             set (&SPVAL, arg_val, arg_typ, 1, 0, HUGE);
  393.             space ( SPVAL );
  394.             break;
  395.  
  396.       case ST :       /* stop(pause) at each page?*/
  397.             set(&PAGESTOP,arg_val,'0',YES,NO,YES);
  398.             break;
  399.       case BP :       /* set pageno arg_val - begin page */
  400.             brk();
  401.             if(((VLINENO<=0)||(VLINENO>=BOTTOM))&&
  402.                 (arg_val==NO_VAL)) break;
  403.             if ( VLINENO > 0 )      space (HUGE);
  404.             set(&CURPAG,arg_val,arg_typ,CURPAG+1,0,9999);
  405.             NEWPAG = CURPAG;
  406.             break;
  407.       case NE :       /*"need"*/
  408.             if (arg_val==NO_VAL) arg_val=2;/*default*/
  409.             need(arg_val);
  410.             break;
  411.  
  412.       case PL :       /* set page length */
  413.             setS(&PLVAL, arg_val, arg_typ, PL_DEF,
  414.             M1VAL+M2VAL+M3VAL+M4VAL+1,HUGE);
  415.             BOTTOM = PLVAL - M3VAL - M4VAL;
  416.             break;
  417.  
  418.       case FF :       /*formfeed*/
  419.             set(&FFEED,arg_val,'0',FF_DEF,NO,YES);
  420.             break;
  421.  
  422.       case SC :       /*space character*/
  423.             if(arg_typ) arg_val=arg_typ;
  424.             setS(&SCVAL,arg_val,'0',SC_INI,BLANK,127);
  425.             break;
  426.  
  427.       case OW :       /*output device width*/
  428.             setS(&OWVAL,arg_val,'0',OW_INI,RMVAL,HUGE);
  429.             break;
  430.       case TS :       /*tabsize*/
  431.             setS(&TABSIZ,arg_val,'0',TS_DEF,1,HUGE);
  432.             break;
  433.  
  434.       case AB :       /*abort*/
  435.             fprintf(STDERR,"\n***USER ABORT***\n");
  436.             exit();
  437.  
  438. #ifdef DEBUGON
  439.       case DB :       /*debug*/
  440.             setS(&debug,arg_val,'0',NO,NO,YES);
  441.             if DEBUG fprintf(STDERR,"\nDEBUG ON...\n");
  442.             else fprintf(STDERR,"\n...END OF DEBUG\n");
  443.             break;
  444. #endif
  445.  
  446.       case TC :       /*translate character flag*/
  447.             if(arg_typ) arg_val=arg_typ;
  448.             setS(&TCVAL,arg_val,'0',TC_DEF,BLANK+1,127);
  449.             break;
  450.  
  451.       case CF :       /*translate character flag*/
  452.             if(arg_typ) arg_val=arg_typ;
  453.             setS(&CFVAL,arg_val,'0',CF_DEF,BLANK+1,127);
  454.             break;
  455.  
  456.       case IC :       /*insert character for macro replace*/
  457.             if(arg_typ) arg_val=arg_typ;
  458.             setS(&ICVAL,arg_val,'0',IC_DEF,BLANK+1,127);
  459.             break;
  460.  
  461.       case TR :       /*translation string defined here*/
  462.             gettr(); 
  463.             break;
  464.  
  465.       case OU :       /*output code string*/
  466.             ocode(); 
  467.             break;
  468.  
  469.       case FR :       /*define fractional spacing code*/
  470.             getfr(); 
  471.             break;
  472.  
  473.       case WH :       /*define whole line spacing code*/
  474.             getwh(); 
  475.             break;
  476.  
  477.       case DS :       /*define string*/
  478.             insert(); 
  479.             break;
  480.  
  481.       case DM :       /*define macro*/
  482.             minsert(); 
  483.             break;
  484.  
  485.       case RG :       /*register variable*/
  486.             dovar(); 
  487.             break;
  488.  
  489.       case DI :       /*diversion to file*/
  490.             dodiv(); 
  491.             break;
  492.  
  493.       case SO :       /*source from file*/
  494.             source(); 
  495.             break;
  496.  
  497.       case PC :       /*printer control*/
  498.             getpc(); 
  499.             break;
  500.  
  501.       case SA :       /*"say" to console*/
  502.             getwrd(LINE,wbuf);      /*skip command*/
  503.             skip_blanks(LINE);
  504.             trunc_bl(LINE);
  505.             fprintf(STDERR,"<%s>\n",LINE);
  506.             break;
  507.  
  508.       case BJ :       /*break with right justification*/
  509.             if(FILL)/*not applicable otherwise*/
  510.             {
  511.                   spread(OUTBUF,
  512.                   min(RMVAL-TIVAL,MAXLINE-1)-OUTW+1,
  513.                   OUTWRDS);
  514.                   brk();
  515.             }
  516.             break;
  517.       }
  518. }
  519.  
  520. start()/*to insure only one entry into TRTBL at a time*/
  521. {
  522.       if(TFLAG)
  523.       {
  524.             fprintf(STDERR,"ILLEGAL double access of TRTBL\n");
  525.             fprintf(STDERR,
  526.                "Simultaneous creation of two definitions not possible\n");
  527.             exit();
  528.       }
  529.       else    TFLAG=TRUE;
  530. }
  531.  
  532. complete()/*to insure only one entry into TRTBL at a time*/
  533. {
  534.       TFLAG=FALSE;
  535. }
  536.  
  537. range(s)
  538. char *s;
  539.       int num;
  540.       num=0;
  541.       while(isdigit(*s)) num=num*10+(*(s++)-'0');
  542.       if(num) FIRSTPAGE=num;
  543.       if(*s=='-')
  544.       {
  545.             s++; 
  546.             num=0;
  547.             while(isdigit(*s)) num=num*10+(*(s++)-'0');
  548.             if(num) LASTPAGE=num;
  549.       }
  550.       else    LASTPAGE=FIRSTPAGE;
  551. }
  552.